/*
 * This file is part of Sparwe.
 *
 *  Sparwe is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Sparwe is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Sparwe.  If not, see <http://www.gnu.org/licenses/>.
 */ 


#ifndef __CONFIGREADER_H__
#define __CONFIGREADER_H__
#include <map>
#include <list>
#include <string>
#include <iostream>

#include "policies/conversionpolicies.h"

namespace sp_core
{	
	/** 
	 * @brief Reads and parses the data in a config file.
	 *
	 * The config file is read on the first method call to the object(constructor is not included in this case). 
	 */

	class ConfigReader
	{
		public:

			/** 
			 * @brief Prepares the reader for parsing a config file according the specified settings.
			 * 
			 * @param filename 
			 * @param sep Separator characters.
			 */
			ConfigReader(std::string filename, std::string sep = "=;");

			/** 
			 * @brief 
			 */
			virtual ~ConfigReader();


			/** 
			 * @brief Verifies so the config is valid.
			 * 
			 * @return 
			 */
			bool VerifyConfig() const;

			/** 
			 * @brief Returns a string with the separator characters.
			 * 
			 * @return 
			 */

			std::string GetSeparators() const;


			/** 
			 * @brief Returns an option by key name. The converter policy is used to converted from a string to the wished type. 
			 * 
			 * @param name 
			 * 
			 * @return 
			 */
			template <typename OptionType, class ConverterPolicy> 
			OptionType GetOption(std::string name)
			{
				for (std::map<std::string, std::string>::iterator iter = mTokens.begin(); iter != mTokens.end(); ++iter)
				{
					if ( iter->first.compare(name) == 0)
					{
						ConverterPolicy policy;
						OptionType value = policy.Convert(iter->second);
						return value;
					}
				}
				return 0;
			}
			

		private:

			/** 
			 * @brief Reads the config file and puts the keys and values in the mTokens variable.
			 * 
			 * @return 
			 */
			bool ReadFile();
			
			std::map<std::string, std::string> mTokens;
			std::string mData;
			std::string mSeparators;
			const std::string mFilename;
	};


}



#endif
